Amazon ECSの新ネットワーク機能”Service Connect”をAWS Copilot CLIで設定してみた #reinvent
prismatixのとばち(@toda_kk)です。
AWS re:Invent 2022にて、Amazon ECS Service Connectという新たな機能が発表されました。
マイクロサービスアーキテクチャなどの構成において、ECSサービス間の通信を簡単に設定できるようにしたアップデートとなっています。詳細については、下記の記事などをご参照ください。
アップデートのアナウンスと共に公開されたAWS公式ブログによると、今回の新機能はCloudFormationやAWS CDKといったIaCツールでもサポートしているそうです。
ECS Service Connect is fully supported in AWS CloudFormation, AWS CDK, AWS Copilot, and AWS Proton for infrastructure provisioning, code deployments, and monitoring of your services.
CDKに関しては、既に試してみた記事が本ブログにて上がっています。
本記事では、AWS Copilotを用いてECS Service Connectを設定する手順を確認してみます。
AWS Copilotについて
AWS Copilotの概要については下記の記事で詳しく解説しているので、ぜひご参照ください。
Service Connectの発表後、AWS re:Invent 2022開催中にCopilotでも新たなバージョン(v1.24.0)がリリースされサポートが開始されました。
AWS CopilotでService Connectを設定してみる
Copilotでは、copilot svc init
コマンドを実行した後、ECSサービスに関する設定を "manifest.yml" というファイルで簡単に管理することができます。
Service Connectを設定する際は、このファイルに下記の項目を追加するだけで済みます。
network: connect: true
例えば、他のECSサービスからの通信を受け付けたいバックエンドに対してService Connectを設定する際は、下記のような設定になるかと思います。
name: backend type: Backend Service image: port: 80 build: backend/Dockerfile cpu: 256 memory: 512 count: 2 exec: true network: connect: true vpc: placement: 'private'
network.connect: true
を設定する他に、 image.port
でリクエストを受け付けるポート番号を指定しておく必要があります。
特にポートを外部に公開する必要のないクライアントとなるServiceに対して、バックエンドのエンドポイントを名前解決できるようにService Connectを有効化する際は、 image.port
の項目なしで設定すればOKです。
name: client type: Backend Service image: build: client/Dockerfile cpu: 256 memory: 512 count: 2 exec: true network: connect: true
上記のマニフェストファイルを元に copilot svc deploy
でECSサービスをデプロイした後、 クライアントからバックエンドのECSサービスを名前解決できるか確認してみます。
copilot svc exec
コマンドを使うと、ECS ExecによってECSサービスのタスクに対してコマンドを実行できます。
$ copilot svc exec --name client --task-id xxxxxxx The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Starting session with SessionId: ecs-execute-command-xxxxxxxxxxxxxxxxx # curl http://backend:80 OK # cat /etc/hosts 127.0.0.1 localhost 10.1.0.222 ip-10-1-0-222.ap-northeast-1.compute.internal 127.255.0.1 backend 2600:f0f0:0:0:0:0:0:1 backend
Copilot Service名(上の例では backend
)がそのままECSサービスのエンドポイントとなっており、クライアントのECSサービスから名前解決および通信ができていることが確認できます。
Service Discoveryとの関連
ECSでは以前よりサービス間通信の仕組みとしてService Discovery(サービス検出)の機能が提供され、Copilotでも設定が可能でしたが、その場合もマニフェストファイルから image.port
でポート番号を指定することで設定を有効化する手順となっていました。
実はCopilotでは、Serviceの設定と関係なくEnvironmentを作成した際にCloud Mapの名前空間リソースが作成されます。より具体的には、 copilot env init
コマンドを実行した後、 copilot env deploy
コマンドを実行したタイミングです。
作成される名前空間リソースは ${COPILOT_ENVIRONMENT_NAME}.${COPILOT_APPLICATION_NAME}.local
といった命名規則となります。
そして、Copilotを利用してService DiscoveryおよびService Connectを設定した際は、同じApplication + Environmentであれば上記の名前空間を共有することになります。
Cloud Mapの名前空間には、エンドポイントとなるドメイン名とECSタスクを関連づけるための「サービス」というリソースが作成されるのですが、マニフェストファイルの設定内容によってはCopilot Serviceに応じて複数の「サービス」が作成されます。
image.port
でポート番号が設定されている場合: Service Connectの「サービス」が作成される- 上記の例では、バックエンドのCopilot Serviceのみ作成されている
network.connect: true
が設定されている場合: Service Discoveryの「サービス」が作成される- 上記の例では、クライアントとバックエンドのCopilot Serviceの両方で作成されている
この辺り、Copilotによって具体的なAWSリソースについては抽象化してくれるのですが、実際にどういったAWSリソースが作成されているか把握しておくと、トラブルシューティングの際などいざという時に混乱を防ぐことができるかと思います。
ちなみに、Service Connectではエンドポイントとなるドメイン名に関してエイリアスを設定することができます。
Copilotを用いてService Discoveryを既に設定している場合、ドメイン名は ${COPILOT_SERVICE_NAME}.${COPILOT_ENVIRONMENT_NAME}.${COPILOT_APPLICATION_NAME}.local
といった命名規則によって決まるため、下記のように設定することでService Connectに簡単に移行することができます。
network: connect: alias: ${COPILOT_SERVICE_NAME}.${COPILOT_ENVIRONMENT_NAME}.${COPILOT_APPLICATION_NAME}.local
ただし、上記の命名規則となったのはCopilot v1.9.0以降となっています。それ以前のバージョンを利用してService Discoveryを設定している場合には、命名規則が異なっておりますのでご注意ください。
詳細に関しては下記ページをご参照ください。
Copilotでは簡単にService Connectを設定できる
以上、Copilotによる設定手順と、作成されるリソースについて確認してみました。
マニフェストファイルに項目を数行追加するだけでService Connectを有効化できるので、既にCopilotを使ってECSサービスを構築されている方はぜひ試してみてください。
以上、prismatixのとばち(@toda_kk)でした。